package cn.tuling.v1;

/**
 * 李斯通过在韩子非身边安排间谍，来监视韩非子
 *
 * 缺陷：
 * 1. CPU飙升，过度占用硬件资源
 */
public class ObserverTest {
    public static void main(String[] args) throws InterruptedException {
        LiSi liSi = new LiSi();
        HanFeiZi hanFeiZi = new HanFeiZi();

        Spy watchBreakfast = new Spy(hanFeiZi, liSi, "breakfast");
        watchBreakfast.start();

        Spy watchFun = new Spy(hanFeiZi, liSi, "fun");
        watchFun.start();

        Thread.sleep(1000);

        hanFeiZi.haveBreakfast();
        Thread.sleep(1000);

        hanFeiZi.haveFun();
        Thread.sleep(1000);

        hanFeiZi.haveFun();
        Thread.sleep(1000);

        hanFeiZi.haveFun();
        Thread.sleep(1000);

    }
}

interface IHanFeiZi {
    void haveBreakfast();

    void haveFun();
}

class HanFeiZi implements IHanFeiZi {
    private boolean isHavingBreakfast;
    private boolean isHavingFun;

    @Override
    public void haveBreakfast() {
        System.out.println("韩非子吃早饭");
        setHavingBreakfast(true);
    }

    @Override
    public void haveFun() {
        System.out.println("韩非子娱乐");
        setHavingFun(true);
    }

    public boolean isHavingBreakfast() {
        return isHavingBreakfast;
    }

    public void setHavingBreakfast(boolean havingBreakfast) {
        isHavingBreakfast = havingBreakfast;
    }

    public boolean isHavingFun() {
        return isHavingFun;
    }

    public void setHavingFun(boolean havingFun) {
        isHavingFun = havingFun;
    }
}

interface ILiSi {
    void update(String context);
}

class LiSi implements ILiSi {

    @Override
    public void update(String context) {
        System.out.println("李斯：观察到了韩非子的活动");
        this.reportToQinShiHuang(context);
        System.out.println("李斯：报告完毕");
    }

    private void reportToQinShiHuang(String context) {
        System.out.println("李斯：报告秦老板，韩非子有了新活动   " + context);
    }
}

class Spy extends Thread {
    private HanFeiZi hanFeiZi;
    private LiSi liSi;
    private String type;

    public Spy(HanFeiZi hanFeiZi, LiSi liSi, String type) {
        this.hanFeiZi = hanFeiZi;
        this.liSi = liSi;
        this.type = type;
    }

    @Override
    public void run() {
        while (true) {
            if (type.equalsIgnoreCase("breakfast")) {
                if (hanFeiZi.isHavingBreakfast()) {
                    liSi.update("韩非子吃饭了");
                    this.hanFeiZi.setHavingBreakfast(false);
                }
            } else {
                if (hanFeiZi.isHavingFun()) {
                    liSi.update("韩非子娱乐了");
                    hanFeiZi.setHavingFun(false);
                }
            }
        }
    }
}